#!/usr/bin/python
# encoding: utf-8
# description: get local ip address

import sys
import os
from ftplib import FTP

_XFER_FILE = "FILE"
_XFER_DIR = "DIR"


class Xfer(object):
    """''
    @note: upload local file or dirs recursively to ftp server
    """

    def __init__(self):
        self.ftp = None

    def __del__(self):
        pass

    def setFtpParams(self, ip, uname, pwd, port=2121, timeout=60):
        self.ip = ip
        self.uname = uname
        self.pwd = pwd
        self.port = port
        self.timeout = timeout

    def initEnv(self):
        if self.ftp is None:
            self.ftp = FTP()
            print("### connect ftp server: %s ..." % self.ip)
            self.ftp.connect(self.ip, self.port, self.timeout)
            self.ftp.login(self.uname, self.pwd)
            print(self.ftp.getwelcome())

    def clearEnv(self):
        if self.ftp:
            self.ftp.close()
            print("### disconnect ftp server: %s!" % self.ip)
            self.ftp = None

    def __filetype(self, src):
        if os.path.isfile(src):
            index = src.rfind("\\")
            if index == -1:
                index = src.rfind("/")
            return _XFER_FILE, src[index + 1 :]
        elif os.path.isdir(src):
            return _XFER_DIR, ""

    def upload(self, src, destdir, dirOverride=True):  # dirOverride=True, 目标文件夹被覆盖
        filetype, filename = self.__filetype(src)
        self.initEnv()
        if dirOverride == False:
            prog_name = destdir.split("/")[-1]
            dst_dir = self.ftp.nlst(destdir.split("/")[-2])
            if prog_name in dst_dir:
                self.clearEnv()
                return False
        if filetype == _XFER_DIR:
            self.srcDir = src
            self.upload_dir(src, destdir)
        elif filetype == _XFER_FILE:
            dest_file_path = os.path.join(destdir, filename)
            self.uploadFile(src, dest_file_path)
        self.clearEnv()

    def upload_dir(self, path_source, target_dir=None):
        files = os.listdir(path_source)
        # 先记住之前在哪个工作目录中
        last_dir = os.path.abspath(".")
        # 然后切换到目标工作目录
        os.chdir(path_source)
        if target_dir:
            current_dir = self.ftp.pwd()
            try:
                self.ftp.mkd(target_dir)
            except Exception:
                pass
            finally:
                self.ftp.cwd(os.path.join(current_dir, target_dir))

        for file_name in files:
            current_dir = self.ftp.pwd()
            if os.path.isfile(path_source + r"/{}".format(file_name)):
                file_path = os.path.join(path_source, file_name)
                self.upload_file(file_path, current_dir)
            elif os.path.isdir(path_source + r"/{}".format(file_name)):
                current_dir = self.ftp.pwd()
                try:
                    self.ftp.mkd(file_name)
                except:
                    pass
                self.ftp.cwd("%s/%s" % (current_dir, file_name))
                self.upload_dir(path_source + r"/{}".format(file_name))
            # 之前路径可能已经变更，需要再回复到之前的路径里
            self.ftp.cwd(current_dir)
        os.chdir(last_dir)

    def upload_file(self, file_path, target_dir=None):
        # 记录当前 ftp 路径
        path_source, file_name = os.path.split(file_path)
        cur_dir = self.ftp.pwd()
        if target_dir:
            try:
                self.ftp.mkd(target_dir)
            except:
                pass
            finally:
                self.ftp.cwd(os.path.join(cur_dir, target_dir))
        path_source, file_name = os.path.split(file_path)
        file = open(file_path, "rb")  # file to send
        self.ftp.storbinary("STOR %s" % file_name, file)  # send the file
        file.close()  # close file
        self.ftp.cwd(cur_dir)
